<template>
  <span ref="mainRef" class="whitespace-pre-wrap"></span>
  <span ref="defaultRef" class="hidden">
    <slot></slot>
  </span>
</template>

<script lang="ts" setup>
import Typed from 'typed.js'

const mainRef = ref<HTMLSpanElement>()
const defaultRef = ref<HTMLSpanElement>()
const vueTyped = ref<Typed>()

const props = withDefaults(
  defineProps<{
    strings: string[]
    typeSpeed: number // 打字速度（毫秒）
    startDelay?: number //键入开始前的时间（以毫秒为单位）
    backSpeed?: number // 后退间隔速度（以毫秒为单位）
    smartBackspace?: boolean // 启用/禁用智能退格键
    shuffle?: boolean // 启用/禁用字符串的洗牌
    backDelay?: number // 后退前的时间（以毫秒为单位）
    fadeOut?: boolean // 启用/禁用淡出动画
    fadeOutClass?: string // 用于淡入淡出动画的 CSS 类
    fadeOutDelay?: number // 淡出延迟（以毫秒为单位）
    loop?: boolean // 启用/禁用循环
    loopCount?: number //循环次数或Infinity
    showCursor?: boolean // 显示/隐藏光标
    cursorChar?: string // 光标图标
    autoInsertCss?: boolean // 将光标的 CSS 插入到 HTML 中，并将 fadeOut 插入 HTML
    attr?: string // 键入的属性
    bindInputFocusEvents?: boolean // 如果 el 是文本输入或文本区域，则绑定到焦点和模糊
    contentType?: string // “html”或“null”表示明文
    onComplete?: (...args: any) => void // 键入完成后
    prestringTyped?: (...args: any) => void // 键入字符串前
    onstringTyped?: (...args: any) => void // 	键入字符串时
    onLaststringBackspaced?: (...args: any) => void // 键入最后一个字符串并退格时
    onTypingPaused?: (...args: any) => void // 键入暂停时
    onTypingResumed?: (...args: any) => void // 恢复打字时
    onReset?: (...args: any) => void // 重置类型化实例时
    onStop?: (...args: any) => void // 类型化实例停止时
    onStart?: (...args: any) => void // 类型化实例启动时
    onDestroy?: (...args: any) => void // 类型化实例销毁时
  }>(),
  {
    typeSpeed: 50, // 输入延迟
    autoInsertCss: true, //将光标的 CSS 插入到 HTML 中，并将 fadeOut 插入 HTML?
    smartBackspace: true, // 退格？

    // shuffle: true,
    // fadeOut: true,
    // bindInputFocusEvents: true,
  },
)

onMounted(() => {
  const options = Object.entries(props).reduce(
    (a, [key, value]) => {
      if (value !== undefined) a[key] = value
      return a
    },
    {} as Record<string, any>,
  ) // 把undefined过滤掉
  const defaultStr = defaultRef.value?.innerHTML.toString()
  if (defaultStr) {
    options.strings.unshift(defaultStr)
  }
  vueTyped.value = new Typed(mainRef.value, options)
})

onBeforeUnmount(() => {
  vueTyped.value?.destroy()
})

function dispatch(name: 'destroy' | 'toggle' | 'stop' | 'start' | 'destroy' | 'reset') {
  vueTyped.value?.[name]()
}

defineExpose({
  dispatch,
})
</script>
